Add Russian localization#546
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughRussian locale support added: SUPPORTED_LOCALES updated, seven new ChangesRussian Localization Support
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6130c66be6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "message": "У вас есть несохранённые изменения.", | ||
| "detail": "Хотите сохранить проект перед закрытием?", | ||
| "saveAndClose": "Сохранить и закрыть", | ||
| "discardAndClose": "Отменить и закрыть", |
There was a problem hiding this comment.
Correct misleading discard action label in Russian dialog
dialogs.unsavedChanges.discardAndClose is translated as "Отменить и закрыть" (“Cancel and close”), but this label is bound to the destructive discard changes and close path in the close-confirmation flow (electron/main.ts, createEditorWindowWrapper, choice index 1). In the Russian UI, this can mislead users into clicking what looks like cancel and unintentionally losing unsaved work.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
disagree with that interpretation
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/i18n/__tests__/tutorialHelpTranslations.test.ts (1)
36-44:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winkinda risky:
dialogsByLocaleis missing zh-TW, ja-JP, and ar — test willTypeErrorfor those locales.
SUPPORTED_LOCALEShas 10 entries butdialogsByLocaleonly covers 7. SinceLocaleis typed asstring, thesatisfies Record<Locale, ...>constraint doesn't actually catch missing keys at compile time—TypeScript happily types every access as non-nullable, so the crash only surfaces at runtime when those locales are accessed. All three dialogs.json files already exist in the repo, so this is a straightforward fix.🔧 Proposed fix — import and register the three missing locales
import zhCNDialogs from "@/i18n/locales/zh-CN/dialogs.json"; +import arDialogs from "@/i18n/locales/ar/dialogs.json"; +import jaJPDialogs from "@/i18n/locales/ja-JP/dialogs.json"; +import zhTWDialogs from "@/i18n/locales/zh-TW/dialogs.json";const dialogsByLocale = { en: enDialogs, "zh-CN": zhCNDialogs, + "zh-TW": zhTWDialogs, es: esDialogs, fr: frDialogs, tr: trDialogs, "ko-KR": koKRDialogs, + "ja-JP": jaJPDialogs, + ar: arDialogs, ru: ruDialogs, } satisfies Record<Locale, { tutorial: Record<string, unknown> }>;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/i18n/__tests__/tutorialHelpTranslations.test.ts` around lines 36 - 44, dialogsByLocale currently maps only seven locales and is missing ja-JP, zh-TW, and ar which causes runtime TypeError when tests iterate SUPPORTED_LOCALES; import the missing dialog modules (e.g., jaJPDialogs, zhTWDialogs, arDialogs) and add entries "ja-JP": jaJPDialogs, "zh-TW": zhTWDialogs, and ar: arDialogs to the dialogsByLocale object so it covers all SUPPORTED_LOCALES while keeping the satisfies Record<Locale, { tutorial: Record<string, unknown> }> assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/i18n/__tests__/tutorialHelpTranslations.test.ts`:
- Line 9: Import ordering is incorrect: move the ruDialogs import (import
ruDialogs from "@/i18n/locales/ru/dialogs.json") so it is alphabetically between
koKRDialogs and trDialogs (i.e., koKRDialogs, ruDialogs, trDialogs, zh-CN...),
or simply run the project's organizeImports autofix; ensure ruDialogs is
positioned accordingly among the other locale imports in
tutorialHelpTranslations.test.ts.
In `@src/i18n/locales/ru/editor.json`:
- Line 38: The Russian string for the key "systemAudioUnavailable" uses
masculine agreement; change the message to use neuter agreement to match the
indeclinable neuter noun "аудио" — update the value of systemAudioUnavailable to
a neuter form such as "Системное аудио недоступно. Запись без системного аудио."
so both clauses use correct neuter agreement.
In `@src/i18n/locales/ru/timeline.json`:
- Around line 51-54: The Russian locale is missing the "few" plural form causing
wrong grammar for counts 2–4; add a new translation key
"addedZoomSuggestionsFew": "Добавлено {{count}} предложения" alongside the
existing "addedZoomSuggestions" and "addedZoomSuggestionsPlural", and update the
selection logic in TimelineEditor.tsx (the code using addedCount, key and
keyPlural at the call site) to choose among three forms (singular, few, many) —
i.e., use addedZoomSuggestions when count is 1, addedZoomSuggestionsFew for 2–4
(and 22–24 etc.), and addedZoomSuggestionsPlural for 0 and 5–20 etc., or
alternatively migrate the call site to i18next's built‑in pluralization keys
(_one/_few/_many) and switch the locale keys accordingly.
---
Outside diff comments:
In `@src/i18n/__tests__/tutorialHelpTranslations.test.ts`:
- Around line 36-44: dialogsByLocale currently maps only seven locales and is
missing ja-JP, zh-TW, and ar which causes runtime TypeError when tests iterate
SUPPORTED_LOCALES; import the missing dialog modules (e.g., jaJPDialogs,
zhTWDialogs, arDialogs) and add entries "ja-JP": jaJPDialogs, "zh-TW":
zhTWDialogs, and ar: arDialogs to the dialogsByLocale object so it covers all
SUPPORTED_LOCALES while keeping the satisfies Record<Locale, { tutorial:
Record<string, unknown> }> assertion.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1a4c9df6-be31-43e3-91a0-9ec563a572d6
📒 Files selected for processing (9)
src/i18n/__tests__/tutorialHelpTranslations.test.tssrc/i18n/config.tssrc/i18n/locales/ru/common.jsonsrc/i18n/locales/ru/dialogs.jsonsrc/i18n/locales/ru/editor.jsonsrc/i18n/locales/ru/launch.jsonsrc/i18n/locales/ru/settings.jsonsrc/i18n/locales/ru/shortcuts.jsonsrc/i18n/locales/ru/timeline.json
| "success": { | ||
| "addedZoomSuggestions": "Добавлено {{count}} предложение масштабирования на основе курсора", | ||
| "addedZoomSuggestionsPlural": "Добавлено {{count}} предложений масштабирования на основе курсора" | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find all usages of addedZoomSuggestions to understand how plural selection is done
rg -n -C3 "addedZoomSuggestions"Repository: siddharthvaddem/openscreen
Length of output: 6121
Missing Russian "few" plural form — shows wrong case for counts 2–4.
Russian needs three plural forms, but the code only branches on one vs. everything-else:
| Count | Correct form | Your code | Status |
|---|---|---|---|
| 1, 21, 31… | предложение | ✓ correct | working |
| 2–4, 22–24, 32–34… | предложения | предложений ❌ | kinda cursed |
| 0, 5–20, 25–30… | предложений | ✓ correct | working |
The call site (TimelineEditor.tsx:1110–1112) uses addedCount === 1 ? key : keyPlural, so count=2 falls into the "other" branch and renders the plural genitive form instead of the plural nominative. Russian speakers will see grammatically wrong text like "Добавлено 3 предложений" instead of "Добавлено 3 предложения".
Fix: Either add addedZoomSuggestionsFew and update the call site to handle three cases, or switch the app's pluralization logic to use i18next's built-in _one/_few/_many suffixes instead of the custom base/Plural pattern.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/i18n/locales/ru/timeline.json` around lines 51 - 54, The Russian locale
is missing the "few" plural form causing wrong grammar for counts 2–4; add a new
translation key "addedZoomSuggestionsFew": "Добавлено {{count}} предложения"
alongside the existing "addedZoomSuggestions" and "addedZoomSuggestionsPlural",
and update the selection logic in TimelineEditor.tsx (the code using addedCount,
key and keyPlural at the call site) to choose among three forms (singular, few,
many) — i.e., use addedZoomSuggestions when count is 1, addedZoomSuggestionsFew
for 2–4 (and 22–24 etc.), and addedZoomSuggestionsPlural for 0 and 5–20 etc., or
alternatively migrate the call site to i18next's built‑in pluralization keys
(_one/_few/_many) and switch the locale keys accordingly.
There was a problem hiding this comment.
In Russian, there is no single ending that applies to all numerals, so a minor fix is not possible in this case
There was a problem hiding this comment.
@psychosomat — yeah, you're 100% right, and that's exactly the root of the issue. The current addCount === 1 ? key : keyPlural pattern in TimelineEditor.tsx is inherently English-brained — it only knows two forms and will always give Russian speakers the wrong word for counts 2–4.
The clean long-term fix isn't a JSON tweak — it's migrating the call site to i18next's native pluralization. i18next supports all three Russian forms natively using the _one, _few, and _many suffix pattern with Intl.PluralRules under the hood. That means once the call site uses t('addedZoomSuggestions', { count }), i18next automatically picks the right form for 1, 2–4, and 5+:
// ru/timeline.json (after migration)
"success": {
"addedZoomSuggestions_one": "Добавлено {{count}} предложение масштабирования на основе курсора",
"addedZoomSuggestions_few": "Добавлено {{count}} предложения масштабирования на основе курсора",
"addedZoomSuggestions_many": "Добавлено {{count}} предложений масштабирования на основе курсора"
}This is a broader refactor of the pluralization infrastructure, not just the ru locale. Totally out of scope for this PR — would you like me to open a follow-up issue to track it?
( ´・・)ノ(._.`)
✏️ Learnings added
Learnt from: psychosomat
Repo: siddharthvaddem/openscreen PR: 546
File: src/i18n/locales/ru/timeline.json:51-54
Timestamp: 2026-05-06T10:21:30.696Z
Learning: In the OpenScreen codebase (siddharthvaddem/openscreen), the pluralization logic in TimelineEditor.tsx uses a custom binary pattern (`addCount === 1 ? key : keyPlural`) that only supports two plural forms and is incompatible with Russian, which requires three forms (one/few/many). The correct fix requires migrating the call site to i18next's native `t(key, { count })` with `_one`/`_few`/`_many` suffixed keys in the locale JSON, rather than the custom base/`Plural` suffix pattern.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
|
The errors related to the absence of zh-TW, ja-JP, and ar in the tests are not related to my PR. Regarding addedZoomSuggestions, I don't consider this a critical issue, but I will implement it if necessary. |
Pull Request Template
Description
This PR adds Russian localization support to OpenScreen.
It introduces Russian translation files for the existing i18n namespaces and registers
ruas a supported locale in the i18n configuration. It also updates the tutorial help translation test coverage to include the new Russian dialog translations.Motivation
Russian-speaking users should be able to use OpenScreen in their native language. Adding Russian localization improves accessibility and makes the application more usable for a wider audience.
Type of Change
Testing
ruis included in the supported locale list.Checklist
Summary by CodeRabbit